<template>
  <!-- 搜索 -->
  <el-card style="height: 80px">
    <search-comp
      :label="label"
      @handleSearch="handleSearch"
      @handleReset="handleReset"
    />
  </el-card>
  <!-- 表单 -->
  <el-card style="margin: 10px 0px">
    <el-button
      icon="Plus"
      v-if="hasPermission('sys:role:add')"
      type="primary"
      size="default"
      @click="addRole"
      >添加角色</el-button
    >
    <span style="margin-left: 20px; color: #bcbcbd; font-size: 15px"
      >*勾选一条数据进行角色菜单授权</span
    >
    <!-- table展示角色信息 -->
    <el-table
      style="margin: 10px 0px"
      :data="roleArr"
      @selection-change="handleTableCurrentChange"
    >
      <el-table-column type="selection"></el-table-column>
      <el-table-column label="ID" prop="id"></el-table-column>
      <el-table-column
        label="角色名"
        prop="name"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column
        label="备注"
        prop="remark"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column
        label="创建人"
        prop="createBy"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column
        label="创建时间"
        prop="createTime"
        show-overflow-tooltip
      ></el-table-column>
      <el-table-column
        label="操作"
        fixed="right"
        width="150px"
        v-if="
          hasPermission('sys:role:edit') || hasPermission('sys:role:delete')
        "
      >
        <template #default="scope">
          <el-button
            type="primary"
            link
            size="small"
            icon="Edit"
            @click="updateUser(scope.row)"
            v-if="hasPermission('sys:role:edit')"
            >编辑</el-button
          >
          <el-popconfirm
            :title="`你确定要删除${scope.row.name}?`"
            width="260px"
            @confirm="deleteUser(scope.row.id)"
            v-if="hasPermission('sys:role:delete')"
          >
            <template #reference>
              <el-button link type="danger" size="small" icon="Delete"
                >删除</el-button
              >
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>
  </el-card>
  <!-- 分页 -->
  <el-card>
    <pagination
      :pageNum="pageNum"
      :pageSize="pageSize"
      :total="total"
      @handleCurrentChange="handleCurrentChange"
      @handleSizeChange="handleSizeChange"
    />
  </el-card>
  <!--角色菜单，表格树内容栏-->
  <el-card style="margin: 10px 0px" v-if="isRoleMunu">
    <div class="menu-container">
      <div class="menu-header">
        <span><strong>角色菜单授权</strong></span>
      </div>
      <el-tree
        :data="menuData"
        size="mini"
        show-checkbox
        node-key="id"
        :props="defaultPropss"
        style="width: 100%; padding-top: 20px"
        ref="menuTree"
        :render-content="renderContent"
        element-loading-text="拼命加载中"
        @check-change="handleMenuCheckChange"
        v-loading="menuLoading"
        :check-strictly="true"
      >
      </el-tree>
      <div
        style="
          float: left;
          padding-left: 24px;
          padding-top: 12px;
          padding-bottom: 4px;
        "
      >
        <el-checkbox
          v-model="checkAll"
          @change="handleCheckAll"
          :disabled="selectRole.id == null"
          ><b>全选</b></el-checkbox
        >
      </div>
      <div
        style="
          float: right;
          padding-right: 15px;
          padding-top: 4px;
          padding-bottom: 4px;
        "
      >
        <el-button :disabled="selectRole.id == null" @click="resetSelection"
          >重置</el-button
        >
        <el-button
          type="primary"
          :disabled="selectRole.id == null"
          @click="submitAuthForm"
          v-loading="authLoading"
          >确认</el-button
        >
      </div>
    </div>
  </el-card>
  <!-- 新增或者编辑 -->
  <drawer
    ref="drawerRoleRef"
    @cancel="handleCancelRole"
    @submit="handleSubmitRole"
  >
    <template v-slot:title>
      <h4>{{ roleParams.id ? "更新用户" : "添加用户" }}</h4>
    </template>
    <template v-slot:content>
      <el-form
        ref="formRef"
        label-width="auto"
        :model="roleParams"
        :rules="rules"
      >
        <el-form-item label="角色名" prop="name">
          <el-input
            placeholder="请您输入角色名"
            v-model="roleParams.name"
          ></el-input>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input
            type="textarea"
            placeholder="请您输入备注"
            maxlength="100"
            show-word-limit
            v-model="roleParams.remark"
          ></el-input>
        </el-form-item>
      </el-form>
    </template>
  </drawer>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive } from "vue";
import {
  reqRoleList,
  reqDeleteRole,
  reqAddOrUpdateRole,
  reqFindRoleMenus,
  reqSaveRoleMenus,
} from "@/api/acl/role";
import { reqFindMenuTree } from "@/api/acl/menu";
import type {
  Roles,
  IPage,
  IRoleListResponseData,
  IRole,
} from "@/api/acl/type";
import { validatorRoleName } from "@/utlis/validator";
import { ElMessage, ElTag, ElRow, ElCol } from "element-plus";
import IconComp from "@/components/IconComp/index.vue";
import { hasPermission } from "@/utlis/permission";
const label = ref<string>("角色名");
//默认页码
const pageNum = ref<number>(1);
//一页展示几条数据
const pageSize = ref<number>(5);
//用户总个数
const total = ref<number>(0);
//搜索条件
const keyword = ref<string>("");
const roleArr = ref<Roles>([]);
const drawerRoleRef = ref();
//获取form组件实例
const formRef = ref<any>();
//收集用户信息的响应式数据
const roleParams = reactive<IRole>({
  name: "",
  remark: "",
});
const menuData = ref([]);
const defaultPropss = ref({
  children: "children",
  label: "name",
});
const renderContent = (h: any, { node, data }: any) => {
  console.log(node);
  return h("div", { class: "column-container", style: "width:100%;" }, [
    h(
      ElRow,
      { gutter: "20" },
      [h(ElCol, { span: "4", class: "el-col-4" }, [h("div", {}, [data.name])])],
      [
        h(ElCol, { span: "4", class: "el-col-4" }, [
          h("div", {}, [
            h(
              ElTag,
              {
                type: `${data.type === 0 ? "" : data.type === 1 ? "success" : "info"}`,
                size: "small",
              },
              [data.type === 0 ? "目录" : data.type === 1 ? "菜单" : "按钮"],
            ),
          ]),
        ]),
      ],
      [
        h(ElCol, { span: "4", class: "el-col-4" }, [
          h("div", {}, [h(IconComp, { icon: data.icon })]),
        ]),
      ],
      [
        h(ElCol, { span: "4", class: "el-col-4" }, [
          h("div", {}, [data.parentName ? data.parentName : "顶级菜单"]),
        ]),
      ],
      [
        h(ElCol, { span: "4", class: "el-col-4" }, [
          h("div", {}, [data.url ? data.url : "\t"]),
        ]),
      ],
    ),
  ]);
};
onMounted(() => {
  inintData();
});
const inintData = async () => {
  const perams: IPage = {
    pageNum: pageNum.value,
    pageSize: pageSize.value,
    params: {
      name: keyword.value,
    },
  };
  const res: IRoleListResponseData = await reqRoleList(perams);
  if (res.code == 200) {
    total.value = res.data.totalSize;
    roleArr.value = res.data.content;
  }
};
// 获取数据
const menuLoading = ref(false);
const findTreeData = async () => {
  menuLoading.value = true;
  const res = await reqFindMenuTree();
  menuData.value = res.data;
  menuLoading.value = false;
};
//分页器下拉菜单的自定义事件的回调
const handleCurrentChange = (val: number) => {
  pageNum.value = val;
  inintData();
};
const handleSizeChange = (val: number) => {
  pageSize.value = val;
  inintData();
};
//搜索
const handleSearch = (val: string) => {
  keyword.value = val;
  pageNum.value = 1;
  inintData();
};
//重置
const handleReset = () => {
  keyword.value = "";
  pageNum.value = 1;
  inintData();
};
//添加角色
const addRole = () => {
  drawerRoleRef.value.open();
  //清空数据
  Object.assign(roleParams, {
    id: undefined,
    name: "",
    remark: "",
  });
};
//编辑
const updateUser = (row: any) => {
  console.log(row);
  //抽屉显示出来
  addRole();
  //存储收集已有的账号信息
  Object.assign(roleParams, row);
};

//删除
const deleteUser = async (id: any) => {
  let params = [];
  let idArray = (id + "").split(",");
  for (let i = 0; i < idArray.length; i++) {
    params.push({ id: idArray[i] });
  }
  const res = await reqDeleteRole(params);
  if (res.code === 200) {
    ElMessage({
      type: "success",
      message: "删除成功",
    });
    inintData();
  } else {
    ElMessage({
      type: "error",
      message: res.msg,
    });
  }
};

//表单校验的规则对象
const rules = {
  //角色名
  name: [{ required: true, trigger: "blur", validator: validatorRoleName }],
};

//关闭
const handleCancelRole = () => {
  drawerRoleRef.value.close();
};

//保存
const handleSubmitRole = async () => {
  //点击保存按钮的时候,务必需要保证表单全部复合条件在去发请求
  await formRef.value.validate();
  //按钮加载
  drawerRoleRef.value.showloading();
  let params: any = Object.assign({}, roleParams);
  const res = await reqAddOrUpdateRole(params);
  //添加或者更新成功
  if (res.code == 200) {
    //关闭抽屉
    handleCancelRole();
    //提示消息
    ElMessage({
      type: "success",
      message: roleParams.id ? "编辑成功" : "添加成功",
    });
    drawerRoleRef.value.hideloading();
    //获取最新的全部账号的信息
    pageNum.value = 1;
    inintData();
  } else {
    //关闭抽屉
    handleCancelRole();
    //提示消息
    ElMessage({
      type: "error",
      message: res.msg,
    });
    drawerRoleRef.value.hideloading();
  }
};

//当表格的当前行发生变化的时候会触发该事件，如果要高亮当前行，请打开表格的 highlight-current-row 属性
const selectRole = ref({} as any);
const menuTree = ref();
const currentRoleMenus = ref([]);
const checkAll = ref<boolean>(false);
const isRoleMunu = ref<boolean>(false);
const handleTableCurrentChange = async (val: any) => {
  if (val.length > 1 || val.length == 0) {
    ElMessage({
      type: "info",
      message: "请勾选一条数据",
    });
    isRoleMunu.value = false;
    return;
  }
  isRoleMunu.value = true;
  findTreeData();
  selectRole.value = val[0];
  const res = await reqFindRoleMenus(val[0].id);
  currentRoleMenus.value = res.data;
  menuTree.value.setCheckedNodes(res.data);
};

//全选操作
const handleCheckAll = () => {
  if (checkAll.value) {
    const allMenus: any = [];
    checkAllMenu(menuData.value, allMenus);
    menuTree.value.setCheckedNodes(allMenus);
  } else {
    menuTree.value.setCheckedNodes([]);
  }
};
// 递归全选
const checkAllMenu = (menuData: any, allMenus: any) => {
  menuData.forEach((menu: any) => {
    allMenus.push(menu);
    if (menu.children) {
      checkAllMenu(menu.children, allMenus);
    }
  });
};

// 重置选择
const resetSelection = () => {
  checkAll.value = false;
  menuTree.value.setCheckedNodes(currentRoleMenus.value);
};

// 树节点选择监听
const handleMenuCheckChange = (data: any, check: boolean) => {
  if (check) {
    // 节点选中时同步选中父节点
    let parentId = data.parentId;
    menuTree.value.setChecked(parentId, true, false);
  } else {
    // 节点取消选中时同步取消选中子节点
    if (data.children != null) {
      data.children.forEach((element: any) => {
        menuTree.value.setChecked(element.id, false, false);
      });
    }
  }
};
//角色菜单授权提交
const authLoading = ref<boolean>(false);
const submitAuthForm = async () => {
  let roleId = selectRole.value.id;
  if ("admin" == selectRole.value.name) {
    ElMessage({
      type: "error",
      message: "超级管理员拥有所有菜单权限，不允许修改！",
    });
    return;
  }
  authLoading.value = true;
  let checkedNodes = menuTree.value.getCheckedNodes(false, true);
  let roleMenus: any = [];
  for (let i = 0, len = checkedNodes.length; i < len; i++) {
    let roleMenu = { roleId: roleId, menuId: checkedNodes[i].id };
    roleMenus.push(roleMenu);
  }
  const res = await reqSaveRoleMenus(roleMenus);
  if (res.code == 200) {
    ElMessage({
      type: "success",
      message: "操作成功",
    });
  } else {
    ElMessage({
      type: "error",
      message: res.msg,
    });
  }
  authLoading.value = false;
};
</script>
<style lang="scss" scoped>
.menu-container {
  margin-top: 10px;

  .menu-header {
    padding-left: 8px;
    padding-bottom: 5px;
    text-align: left;
    font-size: 16px;
    color: rgb(20, 89, 121);
  }
}

.column-container {
  width: 100%;
}
</style>
